package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ws
 * Date: 2023-07-06
 * Time: 21:11
 */
public class UdpEchoSever {
    //定义一个socket对象
    //网络通信，必须通过socket对象
    private DatagramSocket socket = null;

    //绑定一个端口，不一定成功
    //某个端口被别的进程占用，就会失败
    //同一个主机，一个端口，同一时刻，只能被一个进程占用
    public UdpEchoSever(int port) throws SocketException {
        //构造socket的同时，指定关联/绑定的端口
        socket = new DatagramSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动");
        while (true) {
            //每次循环的三件事
            //1. 读取请求并解析
            //构造空的空间，分配内存空间（但是没有数据）
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            //有数据就立即接收，没有，receive就阻塞等待，直到客户端的数据发送过来
            socket.receive(requestPacket);
            //为了方便处理,从二进制还原回字符串
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
            //2. 根据请求响应
            String response = process(request);
            //3. 把响应结果写回客户端
            //重新构造一个DatagramPacket
            //需要指定发送回的地址，requestPacket.getSocketAddress()该方法包含了客户端的ip和端口号
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.length(), requestPacket.getSocketAddress());
            //发送回去
            socket.send(responsePacket);
            //打印日志，便于观察
            System.out.printf("[%s : %d] req: %s, resp: %s\n", responsePacket.getAddress().toString(), requestPacket.getPort(), request, response);
        }
    }

    //处理方法
    //回显程序直接返回相同的数据
    public String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoSever sever = new UdpEchoSever(9090);
        sever.start();
    }
}
